package com.example.demo.account.web;

import com.example.demo.account.entity.*;
import com.example.demo.account.service.UserRoleService;
import com.example.demo.account.service.impl.DljlServiceImpl;
import com.example.demo.account.service.impl.RoleServiceImpl;
import com.example.demo.account.service.impl.UserServiceImpl;
import com.example.demo.common.utils.BCryptUtil;
import com.example.demo.common.utils.Constant;
import com.example.demo.common.utils.SpringSecurityUtils;
import com.example.demo.information.service.SchoolService;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import io.swagger.annotations.Api;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.security.Security;
import java.util.*;

/**
 * 描述：
 *
 * @author littlecar
 * @date 2019/9/12 10:11
 */
@Controller
//@Api(value = "/user")
public class UserController {
    @Autowired
    private UserServiceImpl userService;

    @Autowired
    private DljlServiceImpl dljlService;
    @Autowired
    private RoleServiceImpl roleService;
    @Autowired
    private UserRoleService userRoleService;
    @Autowired
    private SchoolService schoolService;


    @RequestMapping("/toUserList")
    public String toUserList() {
        return "user/userList";
    }

    @RequestMapping("/userList")
    @ResponseBody
    public Map<String,Object> userList( String name,Integer page,Integer limit) {
        Map<String, Object> map = new HashMap<>();
        String roles = "";
        List<UserInfo> userInfoList = new LinkedList <>();
        List<SysUser> userList = new LinkedList<>();
        List<SysUser> allUserList =new LinkedList<>();
        int pages = (page - 1) * limit;
        if (StringUtils.isNotEmpty(name)) {
            name = "%" + name + "%";
            userList = userService.findPageByNameLike(name,pages,limit);
            allUserList = userService.findByNameLike(name);
        }else{
            userList = userService.findPageAll(pages,limit);
            allUserList = userService.findAll();
        }
        for (SysUser user :
                userList) {
            UserInfo userInfo = new UserInfo();
            userInfo.setId(user.getId());
            userInfo.setUsername(user.getUsername());
            userInfo.setName(user.getName());
            userInfo.setSex(user.getSex());
            userInfo.setSfz(user.getSfz());
            userInfo.setEmail(user.getEmail());
            userInfo.setMobile(user.getMobile());
            userInfo.setStatus(user.getStatus());
            userInfo.setLastTime(dljlService.findLastTimeByUsername(user.getUsername()));
            Set<SysUserRole> sysUserRoles = user.getSysUserRoles();
            int i=0;
            for (SysUserRole userRole :
                    sysUserRoles) {
                if(i==sysUserRoles.size()-1){
                    if (!roles.contains(Constant.roleMap.get(Constant.roleIdMap.get(userRole.getRole_id())))) {
                        roles += Constant.roleMap.get(Constant.roleIdMap.get(userRole.getRole_id()));
                    }
                }else{
                    if (!roles.contains(Constant.roleMap.get(Constant.roleIdMap.get(userRole.getRole_id())))) {
                        roles+=Constant.roleMap.get(Constant.roleIdMap.get(userRole.getRole_id()))+"/";
                    }
                }
                i++;
            }
            userInfo.setRoles(roles);
            roles="";
            userInfoList.add(userInfo);
        }
        map.put("data", userInfoList);
        map.put("code", 0);
        map.put("msg", "");
        map.put("count", allUserList.size());
        return map;
    }

    @RequestMapping("/toUserAdd")
    public String toUserAdd() {
        return "user/userAdd";
    }
    @RequestMapping("/toUserModify")
        public String toUserModify(@RequestParam("id") Long id,ModelMap map) {
        try {
            if (null != id) {
                Optional<SysUser> op = userService.findById(id);
                SysUser user = op.get();
                Set<SysUserRole> sysUserRoles = user.getSysUserRoles();
                String userRoleStr = "";
                for (SysUserRole userRole :
                        sysUserRoles) {
                    userRoleStr+=userRole.getRole_id();
                }
                map.put("user", user);
                map.put("role", userRoleStr);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "user/userModify";
    }

    @RequestMapping("/userAdd")
    @ResponseBody
    public String userAdd(SysUser user, @RequestParam("role") String role, HttpServletRequest request, HttpServletResponse response) {
        try{
            Long id = user.getId();
            if (null == id ) {//新增
                user.setUsername(user.getSfz());
                user.setPassword(BCryptUtil.encode(user.getSfz().substring(user.getSfz().length()-8,user.getSfz().length())));
                Set<SysUserRole> sysUserRoles = new HashSet<SysUserRole>();
                String[] roles = role.split(",");
                for (String role1 :
                        roles) {
                    SysUserRole userRole = new SysUserRole();
                    userRole.setRole_id(Long.valueOf(role1));
                    userRoleService.save(userRole);
                    sysUserRoles.add(userRole);
                }
                user.setSysUserRoles(sysUserRoles);
                userService.save(user);
            }else{//修改
                Optional<SysUser> optionalSysUser = userService.findById(id);
                SysUser sysUser = optionalSysUser.get();
                SecurityUser currentUserDetails = SpringSecurityUtils.getCurrentUserDetails();
                Long currUserRoleId = currentUserDetails.getCurrUserRoleId();
                SysUserRole currUserRole = userRoleService.findById(currUserRoleId);//用户rolelist
                //Map<role_id,list<SysUserRole>>
                Map<Long,List<SysUserRole>> roleId_userRoleMap = userRoleService.findMapByUserId(sysUser.getId());
                //role_id集合
                Set<Long> userRoleIds = roleId_userRoleMap.keySet();
                ArrayList<String> roles = Lists.newArrayList(role.split(","));
                List<Long> changeRoleId=Lists.newArrayList();
                int num=0;//-1角色有减少，1角色有增加，0不变
                if (userRoleIds.size()>roles.size()) {//角色有减少
                    num=-1;
                    for (Long l:
                            userRoleIds) {
                        if(!roles.contains(String.valueOf(l))){
                            changeRoleId.add(l);
                        }
                    }
                }else if(userRoleIds.size()<roles.size()){//角色有增加
                    num=1;
                    for (String s:
                            roles) {
                        if(!userRoleIds.contains(Long.valueOf(s))){
                            changeRoleId.add(Long.valueOf(s));
                        }
                    }
                }else{//角色不变
                    num=0;
                }
                if (num == 1) {
                    for (Long l:
                    changeRoleId) {
                        SysUserRole s = new SysUserRole();
                        s.setRole_id(l);
                        userRoleService.save(s);
                        Set<SysUserRole> sysUserRoles1 = sysUser.getSysUserRoles();
                        sysUserRoles1.add(s);
                        sysUser.setSysUserRoles(sysUserRoles1);
                    }
                } else if (num==-1) {
                    for (Long l:
                            changeRoleId) {
                        List<SysUserRole> list=userRoleService.findByUserIdAndRoleId(sysUser.getId(), l);
                        Set<SysUserRole> sysUserRoles1 = sysUser.getSysUserRoles();
                        sysUserRoles1.removeAll(list);
                        sysUser.setSysUserRoles(sysUserRoles1);
                        userRoleService.deleteAll(list);
                    }
                }
//                sysUser.setSysUserRoles(sysUserRoles);
                if (!StringUtils.equals(user.getSfz(),sysUser.getSfz())) {
                    sysUser.setUsername(user.getSfz());
                    sysUser.setPassword(BCryptUtil.encode(user.getSfz().substring(user.getSfz().length()-8,user.getSfz().length())));
                }
                sysUser.setStatus(user.getStatus());
                sysUser.setSex(user.getSex());
                sysUser.setMobile(user.getMobile());
                sysUser.setEmail(user.getEmail());
                sysUser.setName(user.getName());
                sysUser.setSfz(user.getSfz());
                userService.save(sysUser);
                if (sysUser.getId().equals(currentUserDetails.getId())) {
                    currentUserDetails=new SecurityUser(sysUser);
                    currentUserDetails.setUserPwd(user.getSfz().substring(user.getSfz().length()-8,user.getSfz().length()));
                    if (!roles.contains(currUserRole.getRole_id())) {//当前用户的角色已经被删除
//                        logout();
//                        response.sendRedirect("/login");
//                        return "redirect:/logout";
                        return "logout";
                    }
                }
            }
            return "success";
        }catch (Exception e){
            e.printStackTrace();
            return "error";
        }
    }

    @RequestMapping("/checkSfzUnique")
    @ResponseBody
    public String checkSfzUnique(@RequestParam("sfz")String sfz,@RequestParam("id")String id) {
        List<SysUser> userLsit = null;
        if (StringUtils.equals("undefined",id) || StringUtils.isEmpty(id) || StringUtils.isBlank(id)) {
            userLsit = userService.findBySfz(sfz);
        }else{
            SysUser sysUser = userService.findById(Long.valueOf(id)).get();
            if (sysUser.getSfz().equals(sfz)) {
                return "false";
            }else{
                userLsit = userService.findBySfz(sfz);
            }
        }
        if (null != userLsit && userLsit.size()>0) {
            return "true";
        }
        return "false";
    }
    @GetMapping("/userDel")
    @ResponseBody
    public String userDel(@RequestParam("id") String id,HttpServletResponse response) {
        try {
            SecurityUser currentUserDetails = SpringSecurityUtils.getCurrentUserDetails();
            String[] ids = id.split(",");
            boolean flag = false;//用来判断删除的是否为当前用户
            for (String id1 :
                    ids) {
                Optional<SysUser> op = userService.findById(Long.valueOf(id1));
                SysUser user = op.get();
                ArrayList<SysUserRole> sysUserRoles = Lists.newArrayList(user.getSysUserRoles());
                userRoleService.deleteAll(sysUserRoles);
                userService.delete(user);
                if (user.getSfz().equals(currentUserDetails.getSfz())) {
                    flag=true;
                }
            }
            if (flag) {
//                response.sendRedirect("/lgout");
                return "logout";
            }
            return "success";
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println(e.toString());
            return "error";
        }
    }

    @GetMapping("/userInfo")
    public String userInfo(ModelMap map) {
        SecurityUser currentUserDetails = SpringSecurityUtils.getCurrentUserDetails();
        map.addAttribute("user", currentUserDetails);
        SysUserRole userRole = userRoleService.findById(currentUserDetails.getCurrUserRoleId());
        String userRoleName = "";
        if (null !=userRole.getSchool_id()) {
            userRoleName = schoolService.findById(userRole.getSchool_id()).getName() +"-"+ Constant.roleMap.get(Constant.roleIdMap.get(userRole.getRole_id()));
        }else{
            userRoleName = Constant.roleMap.get(Constant.roleIdMap.get(userRole.getRole_id()));
        }
        map.addAttribute("userRoleName", userRoleName);
        return "user/userInfo";
    }

    @GetMapping("/toChangePwd")
    public String toChangePwd(ModelMap map) {
        SecurityUser currentUserDetails = SpringSecurityUtils.getCurrentUserDetails();
        map.addAttribute("user", currentUserDetails);
        return "user/changePwd";
    }
    @PostMapping("/checkOldPwd")
    @ResponseBody
    public String checkOldPwd(@RequestParam("oldPassword") String oldPassword,@RequestParam("id")Long id){
        try{
            if(null != id){
                SysUser sysUser = userService.findById(id).get();
                boolean match = BCryptUtil.match(oldPassword, sysUser.getPassword());
                return String.valueOf(match);
            }
            return "false";
        }catch (Exception e){
            e.printStackTrace();
            return "false";
        }
    }

    @PostMapping("/changePwd")
    @ResponseBody
    public String changePwd(@RequestParam("newPwd") String newPwd,@RequestParam("id") Long id) {
        try {
            Optional<SysUser> op = userService.findById(id);
            SysUser user = op.get();
            String pwd = BCryptUtil.encode(newPwd);
            user.setPassword(pwd);
            userService.save(user);
            SecurityUser currentUserDetails = SpringSecurityUtils.getCurrentUserDetails();
            currentUserDetails.setPassword(pwd);
            currentUserDetails.setUserPwd(newPwd);
            return "success";
        } catch (Exception e) {
            e.printStackTrace();
            return "error";
        }
    }

    @PostMapping("/changeStatus")
    @ResponseBody
    public String changeStatus(Long id,Integer status) {
        try{
            Optional<SysUser> op = userService.findById(id);
            SysUser user = op.get();
            if (user.getStatus().intValue()==status) {
                user.setStatus(user.getStatus().intValue()==1?0:1);
            }
            userService.save(user);
            SecurityUser currentUserDetails = SpringSecurityUtils.getCurrentUserDetails();
            currentUserDetails.setStatus(user.getStatus());
            return "success";
        }catch(Exception e){
            e.printStackTrace();
            return "error";
        }
    }

    @RequestMapping("/resetPwd")
    @ResponseBody
    public String resetPwd(@RequestParam("id") String id) {
        try {
            if (StringUtils.isNotEmpty(id)) {
                String[] ids = id.split(",");
                for (String id1 :
                        ids) {
                    SysUser user = userService.findById(Long.valueOf(id)).get();
                    String sfz = user.getSfz();
                    String original_encode = sfz.substring(sfz.length() - 8, sfz.length());
                    if (!BCryptUtil.match(original_encode, user.getPassword())) {
                        user.setPassword(BCryptUtil.encode(original_encode));
                        userService.save(user);
                        SpringSecurityUtils.getCurrentUserDetails().setPassword(BCryptUtil.encode(original_encode));
                        SpringSecurityUtils.getCurrentUserDetails().setUserPwd(original_encode);
                    }
                }
            }
            return "success";
        } catch (Exception e) {
            e.printStackTrace();
            return "error";
        }
    }
}
